/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ie.tcd.cs.railtickets.agent.service.impl;

import ie.tcd.cs.railtickets.agent.config.ConfigProperties;
import ie.tcd.cs.railtickets.agent.service.RequestService;
import ie.tcd.cs.railtickets.commons.dto.BookRequestDTO;
import ie.tcd.cs.railtickets.commons.dto.CancelRequestDTO;
import ie.tcd.cs.railtickets.commons.dto.PriceInfoDTO;
import ie.tcd.cs.railtickets.commons.dto.PriceInfoRequestDTO;
import ie.tcd.cs.railtickets.commons.dto.TicketDTO;
import ie.tcd.cs.railtickets.commons.util.NetUtil;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jgrapht.Graph;

/**
 *
 * @author Wenbo Sun
 */
public class RequestServiceImpl implements RequestService {
    
    private Socket socket;

    public List<TicketDTO> bookTicketsRequest(long pathTimeId, Date travelDate, int sum, String operatorName) {
        BookRequestDTO br = new BookRequestDTO(pathTimeId, travelDate, sum);
        Object result = this.sendObject(operatorName, br);
        this.closeSocket();
        if(result != null && result instanceof List)
            return (List) result;
        return null;
    }

    public List<PriceInfoDTO> getPriceInfosRequest(String sourceStation, String destinationStation, Date travelDate, String operatorName) {
        PriceInfoRequestDTO dir = new PriceInfoRequestDTO(sourceStation, destinationStation, travelDate);
        Object result = this.sendObject(operatorName, dir);
        this.closeSocket();
        if(result != null && result instanceof List)
            return (List) result;
        return null;
    }

    public boolean cancelTicketRequest(String ticketNo, String operatorName) {
        CancelRequestDTO crd = new CancelRequestDTO();
        crd.setTicketNo(ticketNo);
        Object result = this.sendObject(operatorName, crd);
        if (result != null && result instanceof Boolean)
            return (Boolean) result;
        return false;
    }

    public Graph getRailsGraphRequest(String operatorName) {
        Object result = this.sendObject(operatorName, "update graph");
        this.closeSocket();
        if(result != null && result instanceof Graph)
            return (Graph) result;
        return null;
    }

    public String[] getOperatorAddr(String operatorName) {
        String pro = ConfigProperties.getInstance().getProperties().getProperty(operatorName);
        return pro.split(";");
    }



    private Object sendObject(String operatorName, Object object) {
        try {
            String[] pros = this.getOperatorAddr(operatorName);
            socket = new Socket(pros[0], Integer.parseInt(pros[1]));
            return NetUtil.sendObject(socket, object);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(RequestServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnknownHostException ex) {
            Logger.getLogger(RequestServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(RequestServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    private void closeSocket() {
        try {
            if (!socket.isClosed())
                socket.close();
        } catch (IOException ex) {
            Logger.getLogger(RequestServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}
